home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / do.c < prev    next >
C/C++ Source or Header  |  1993-01-22  |  31KB  |  1,220 lines

  1. /*    SCCS Id: @(#)do.c    3.1    92/11/11    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. /* Contains code for 'd', 'D' (drop), '>', '<' (up, down) */
  6.  
  7. #include "hack.h"
  8. #include "lev.h"
  9.  
  10. #include <errno.h>
  11. #ifdef _MSC_VER    /* MSC 6.0 defines errno quite differently */
  12. # if (_MSC_VER >= 600)
  13. #  define SKIP_ERRNO
  14. # endif
  15. #endif
  16. #ifndef SKIP_ERRNO
  17. extern int errno;
  18. #endif
  19.  
  20. #ifdef MFLOPPY
  21. extern struct finfo fileinfo[];
  22. #else
  23. extern boolean level_exists[];
  24. #endif
  25.  
  26. #ifdef SINKS
  27. # ifdef OVLB
  28. static void FDECL(trycall, (struct obj *));
  29. # endif /* OVLB */
  30. STATIC_DCL void FDECL(dosinkring, (struct obj *));
  31. #endif /* SINKS */
  32.  
  33. STATIC_PTR int FDECL(drop, (struct obj *));
  34. STATIC_PTR int NDECL(wipeoff);
  35.  
  36. #ifdef OVL2
  37. static int NDECL(currentlevel_rewrite);
  38. /* static boolean FDECL(badspot, (XCHAR_P,XCHAR_P)); */
  39. #endif
  40.  
  41. #ifdef OVLB
  42.  
  43. static const char NEARDATA drop_types[] =
  44.     { ALLOW_COUNT, GOLD_CLASS, ALL_CLASSES, 0 };
  45.  
  46. int
  47. dodrop()
  48. {
  49.     int result;
  50.  
  51.     if (*u.ushops) sellobj_state(TRUE);
  52.     result = drop(getobj(drop_types, "drop"));
  53.     if (*u.ushops) sellobj_state(FALSE);
  54.     reset_occupations();
  55.  
  56.     return result;
  57. }
  58.  
  59. #endif /* OVLB */
  60. #ifdef OVL0
  61.  
  62. /* Called when a boulder is dropped, thrown, or pushed.  If it ends up
  63.  * in a pool, it either fills the pool up or sinks away.  In either case, 
  64.  * it's gone for good...  If the destination is not a pool, returns FALSE.
  65.  */
  66. boolean
  67. boulder_hits_pool(otmp, rx, ry, pushing)
  68. struct obj *otmp;
  69. register int rx, ry;
  70. boolean pushing;
  71. {
  72.     if (!otmp || otmp->otyp != BOULDER)
  73.         impossible("Not a boulder?");
  74.     else if (!Is_waterlevel(&u.uz) && (is_pool(rx,ry) || is_lava(rx,ry))) {
  75.         boolean lava = is_lava(rx,ry), fills_up;
  76.         const char *what = lava ? "lava" : "water";
  77.         schar ltyp = levl[rx][ry].typ;
  78.         int chance = rn2(10);        /* water: 90%; lava: 10% */
  79.         fills_up = lava ? chance == 0 : chance != 0;
  80.  
  81.         if (fills_up) {
  82.         if (ltyp == DRAWBRIDGE_UP) {
  83.             levl[rx][ry].drawbridgemask &= ~DB_UNDER; /* clear lava */
  84.             levl[rx][ry].drawbridgemask |= DB_FLOOR;
  85.         } else
  86.             levl[rx][ry].typ = ROOM;
  87.  
  88.         delallobj(rx, ry);
  89.         newsym(rx,ry);
  90.         if (pushing) {
  91.             You("push %s into the %s.", the(xname(otmp)), what);
  92.             if (flags.verbose && !Blind)
  93.             pline("Now you can cross it!");
  94.             /* no splashing in this case */
  95.         }
  96.         }
  97.         if (!fills_up || !pushing) {    /* splashing occurs */
  98.         if (pushing ? !Blind : cansee(rx,ry))
  99.             pline("There is a large splash as %s %s the %s.",
  100.             the(xname(otmp)), fills_up ? "fills" : "falls into",
  101.             lava ? "lava" : ltyp==POOL ? "pool" : "moat");
  102.         else if (flags.soundok)
  103.             You("hear a%s splash.", lava ? " sizzling" : "");
  104.         wake_nearby();
  105.  
  106.         if (fills_up && u.uinwater && distu(rx,ry) == 0) {
  107.             You("find yourself on dry land again!");
  108.             u.uinwater = 0;
  109.         } else if (lava && distu(rx,ry) <= 2) {
  110.             You("are hit by molten lava%c",
  111.             Fire_resistance ? '.' : '!');
  112.             losehp(d((Fire_resistance ? 1 : 3), 6),
  113.                "molten lava", KILLED_BY);
  114.         } else if (!fills_up && flags.verbose &&
  115.                (pushing ? !Blind : cansee(rx,ry)))
  116.             pline("It sinks without a trace!");
  117.         }
  118.  
  119.         /* boulder is now gone */
  120.         if (pushing) delobj(otmp);
  121.         else obfree(otmp, (struct obj *)0);
  122.         return TRUE;
  123.     }
  124.     return FALSE;
  125. }
  126.  
  127. /* Used for objects which sometimes do special things when dropped; must be
  128.  * called with the object not in any chain.  Returns 1 if the object is
  129.  * gone.
  130.  */
  131. boolean
  132. flooreffects(obj,x,y,verb)
  133. struct obj *obj;
  134. int x,y;
  135. const char *verb;
  136. {
  137.     struct trap *t;
  138.  
  139.     if (obj->otyp == BOULDER && boulder_hits_pool(obj, x, y, FALSE))
  140.         return TRUE;
  141.     else if (obj->otyp == BOULDER && (t = t_at(x,y)) != 0 &&
  142.          (t->ttyp==PIT || t->ttyp==SPIKED_PIT || t->ttyp==TRAPDOOR)) {
  143.         struct monst *mtmp;
  144.  
  145.         delallobj(x, y);
  146.         if(!Can_fall_thru(&u.uz) && t->ttyp == TRAPDOOR)
  147.             return FALSE;
  148.         if (((mtmp = m_at(x, y)) && mtmp->mtrapped) ||
  149.             (u.utrap && x==u.ux && y==u.uy)) {
  150.             /* u.utrap = 0;     /* player remains trapped. See trap.c */
  151.             if (*verb)
  152.             pline("The boulder %ss into the pit%s.", verb, 
  153.                   (mtmp)? "" : " with you");
  154.             if (mtmp) {
  155.             if (!passes_walls(mtmp->data) && !throws_rocks(mtmp->data))
  156.                 if (hmon(mtmp, obj, TRUE))
  157.                     return FALSE;            /* still alive */
  158.                 else
  159.                     delallobj(x, y);  /* treasure, corpse */
  160.             } else
  161. #ifdef POLYSELF
  162.                 if (!passes_walls(uasmon) && !throws_rocks(uasmon))
  163. #endif
  164.             {
  165.                    losehp(rnd(15), "squished under a boulder",
  166.                              NO_KILLER_PREFIX);
  167.                        return FALSE;
  168.             }
  169.         }
  170.         if (*verb) {
  171.             if (Blind) {
  172.                 if ((x == u.ux) && (y == u.uy))
  173.                     You("hear a CRASH! beneath you.");
  174.                 else
  175.                     You("hear the boulder %s.", verb);
  176.             } else if (cansee(x, y)) {
  177.                 pline("The boulder %sfills a %s.",
  178.                       t->tseen ? "" : "triggers and ",
  179.                       t->ttyp == TRAPDOOR ? 
  180.                       "trap door" : "pit");
  181.             }
  182.         }
  183.         deltrap(t);
  184.         obfree(obj, (struct obj *)0);
  185.         newsym(x,y);
  186.         return TRUE;
  187.     }
  188.     return FALSE;
  189. }
  190.  
  191. #endif /* OVL0 */
  192. #ifdef OVLB
  193.  
  194. void
  195. doaltarobj(obj)  /* obj is an object dropped on an altar */
  196.     register struct obj *obj;
  197. {
  198.     if (Blind) return;
  199.     if (obj->blessed || obj->cursed) {
  200.         pline("There is %s flash as %s hit%s the altar.",
  201.               an(Hallucination ? hcolor() :
  202.              obj->blessed ? amber : Black),
  203.               doname(obj),
  204.               (obj->quan == 1L) ? "s" : "");
  205.         if (!Hallucination) obj->bknown = 1;
  206.     } else {
  207.         pline("%s land%s on the altar.", Doname2(obj),
  208.             (obj->quan == 1L) ? "s" : "");
  209.         if (obj->otyp != GOLD_PIECE)
  210.             obj->bknown = 1;
  211.     }
  212. }
  213.  
  214. #ifdef SINKS
  215. static
  216. void
  217. trycall(obj)
  218. register struct obj *obj;
  219. {
  220.     if(!objects[obj->otyp].oc_name_known &&
  221.        !objects[obj->otyp].oc_uname)
  222.        docall(obj);
  223. }
  224.  
  225. STATIC_OVL
  226. void
  227. dosinkring(obj)  /* obj is a ring being dropped over a kitchen sink */
  228. register struct obj *obj;
  229. {
  230.     register struct obj *otmp,*otmp2;
  231.     register boolean ideed = TRUE;
  232.  
  233.     You("drop %s down the drain.", doname(obj));
  234.     switch(obj->otyp) {    /* effects that can be noticed without eyes */
  235.         case RIN_SEARCHING:
  236.         You("thought your %s got lost in the sink, but there it is!",
  237.             xname(obj));
  238.         dropx(obj);
  239.         trycall(obj);
  240.         return;
  241.         case RIN_LEVITATION:
  242.         pline("The sink quivers upward for a moment.");
  243.         break;
  244.         case RIN_POISON_RESISTANCE:
  245. #ifdef TUTTI_FRUTTI
  246.         You("smell rotten %s.", makeplural(pl_fruit));
  247. #else
  248.         You("smell rotten fruit.");
  249. #endif
  250.         break;
  251.         case RIN_AGGRAVATE_MONSTER:
  252.         pline("Several flies buzz angrily around the sink.");
  253.         break;
  254.         case RIN_SHOCK_RESISTANCE:
  255.         pline("Static electricity surrounds the sink.");
  256.         break;
  257.         case RIN_CONFLICT:
  258.         You("hear loud noises coming from the drain.");
  259.         break;
  260.         case RIN_GAIN_STRENGTH:
  261.         pline("The water flow seems %ser now.",
  262.             (obj->spe<0) ? "weak" : "strong");
  263.         break;
  264.         case RIN_INCREASE_DAMAGE:
  265.         pline("The water's force seems %ser now.",
  266.             (obj->spe<0) ? "small" : "great");
  267.         break;
  268.         default:
  269.         ideed = FALSE;
  270.         break;
  271.     }
  272.     if(!Blind && !ideed) {
  273.         ideed = TRUE;
  274.         switch(obj->otyp) {        /* effects that need eyes */
  275.         case RIN_ADORNMENT:
  276.             pline("The faucets flash brightly for a moment.");
  277.             break;
  278.         case RIN_REGENERATION:
  279.             pline("The sink looks as good as new.");
  280.             break;
  281.         case RIN_INVISIBILITY:
  282.             You("don't see anything happen to the sink.");
  283.             break;
  284.         case RIN_SEE_INVISIBLE:
  285.             You("see some air in the sink.");
  286.             break;
  287.         case RIN_STEALTH:
  288.         pline("The sink seems to blend into the floor for a moment.");
  289.             break;
  290.         case RIN_HUNGER:
  291.             ideed = FALSE;
  292.             for(otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp2) {
  293.             otmp2 = otmp->nexthere;
  294.             if(otmp != uball && otmp != uchain) {
  295.                 pline("Suddenly, %s vanishes from the sink!",
  296.                             doname(otmp));
  297.                 delobj(otmp);
  298.                 ideed = TRUE;
  299.             }
  300.             }
  301.             break;
  302.         case RIN_FIRE_RESISTANCE:
  303.         pline("The hot water faucet flashes brightly for a moment.");
  304.             break;
  305.         case RIN_COLD_RESISTANCE:
  306.         pline("The cold water faucet flashes brightly for a moment.");
  307.             break;
  308.         case RIN_PROTECTION_FROM_SHAPE_CHAN:
  309.             pline("The sink looks nothing like a fountain.");
  310.             break;
  311.         case RIN_PROTECTION:
  312.             pline("The sink glows %s for a moment.",
  313.                 Hallucination ? hcolor() :
  314.                 (obj->spe<0) ? Black : silver);
  315.             break;
  316.         case RIN_WARNING:
  317.             pline("The sink glows %s for a moment.",
  318.                 Hallucination ? hcolor() : White);
  319.             break;
  320.         case RIN_TELEPORTATION:
  321.             pline("The sink momentarily vanishes.");
  322.             break;
  323.         case RIN_TELEPORT_CONTROL:
  324.         pline("The sink looks like it is being beamed aboard somewhere.");
  325.             break;
  326. #ifdef POLYSELF
  327.         case RIN_POLYMORPH:
  328.             pline("The sink momentarily looks like a fountain.");
  329.             break;
  330.         case RIN_POLYMORPH_CONTROL:
  331.     pline("The sink momentarily looks like a regularly erupting geyser.");
  332.             break;
  333. #endif
  334.         }
  335.     }
  336.     if(ideed)
  337.         trycall(obj);
  338.     else
  339.         You("hear the ring bouncing down the drainpipe.");
  340.     if (!rn2(20)) {
  341.         pline("The sink backs up, leaving %s.", doname(obj));
  342.         dropx(obj);
  343.     }
  344.     else
  345.         useup(obj);
  346. }
  347. #endif
  348.  
  349. #endif /* OVLB */
  350. #ifdef OVL0
  351.  
  352. /* some common tests when trying to drop or throw items */
  353. boolean
  354. canletgo(obj,word)
  355. register struct obj *obj;
  356. register const char *word;
  357. {
  358.     if(obj->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)){
  359.            if (*word)
  360.             Norep("You cannot %s something you are wearing.",word);
  361.         return(FALSE);
  362.     }
  363.     if (obj->otyp == LOADSTONE && obj->cursed) {
  364.         if (*word)
  365.             pline("For some reason, you cannot %s the stone%s!",
  366.                 word, plur(obj->quan));
  367.         /* Kludge -- see invent.c */
  368.         if (obj->corpsenm) {
  369.             struct obj *otmp;
  370.  
  371.             otmp = obj;
  372.             obj = obj->nobj;
  373.             obj->quan += otmp->quan;
  374.             obj->owt = weight(obj);
  375.             freeinv(otmp);
  376.             obfree(otmp, obj);
  377.         }
  378.         obj->bknown = 1;
  379.         return(FALSE);
  380.     }
  381. #ifdef WALKIES
  382.     if (obj->otyp == LEASH && obj->leashmon != 0) {
  383.            if (*word)
  384.             pline ("The leash is tied around your %s.",
  385.                     body_part(HAND));
  386.         return(FALSE);
  387.     }
  388. #endif
  389.     return(TRUE);
  390. }
  391.  
  392. STATIC_PTR
  393. int
  394. drop(obj)
  395. register struct obj *obj;
  396. {
  397.     if(!obj) return(0);
  398.     if(!canletgo(obj,"drop"))
  399.         return(0);
  400.     if(obj == uwep) {
  401.         if(welded(uwep)) {
  402.             weldmsg(obj, FALSE);
  403.             return(0);
  404.         }
  405.         setuwep((struct obj *)0);
  406.         if(uwep) return 0; /* lifesaved and rewielded */
  407.     }
  408. #ifdef SINKS
  409.     if((obj->oclass == RING_CLASS) && IS_SINK(levl[u.ux][u.uy].typ)
  410.                             && !u.uswallow) {
  411.         dosinkring(obj);
  412.         return(1);
  413.     }
  414. #endif
  415.     if (IS_ALTAR(levl[u.ux][u.uy].typ) && !u.uswallow) {
  416.         doaltarobj(obj);    /* set bknown */
  417.     } else
  418.         if(flags.verbose) You("drop %s.", doname(obj));
  419.     dropx(obj);
  420.     return(1);
  421. }
  422.  
  423. /* Called in several places - should not produce texts */
  424. void
  425. dropx(obj)
  426. register struct obj *obj;
  427. {
  428.     /* Money is *not* in our inventory */
  429.     if (obj->otyp != GOLD_PIECE) freeinv(obj);
  430.     (void) snuff_candle(obj);
  431.     if(!u.uswallow && obj != uball &&
  432.                   ship_object(obj, u.ux, u.uy, FALSE)) return;
  433.     dropy(obj);
  434. }
  435.  
  436. void
  437. dropy(obj)
  438. register struct obj *obj;
  439. {
  440.     if (!u.uswallow && flooreffects(obj,u.ux,u.uy,"drop")) return;
  441.     if(obj->otyp == CRYSKNIFE)
  442.         obj->otyp = WORM_TOOTH;
  443.     /* uswallow check done by GAN 01/29/87 */
  444.     if(u.uswallow) {
  445.         if (obj->otyp == GOLD_PIECE) {
  446.             u.ustuck->mgold += obj->quan;
  447.             delobj(obj);
  448.         } else if (obj != uball) {    /* mon doesn't pick up ball */
  449.             (void) snuff_candle(obj);   /* security. it's never lit */
  450.             mpickobj(u.ustuck,obj);
  451.         }
  452.     } else  {
  453.         (void) snuff_candle(obj);
  454.         obj->nobj = fobj;
  455.         fobj = obj;
  456.         place_object(obj, u.ux, u.uy);
  457.         if (obj == uball)
  458.             drop_ball(u.ux,u.uy);
  459.         else
  460.             sellobj(obj, u.ux, u.uy);
  461.         stackobj(obj);
  462.         if(Blind && Levitation)
  463.             map_object(obj, 0);
  464.         newsym(u.ux,u.uy);    /* remap location under self */
  465.     }
  466. }
  467.  
  468. /* drop several things */
  469. int
  470. doddrop()
  471. {
  472.     int result;
  473.  
  474.     if (*u.ushops) sellobj_state(TRUE);
  475.     result = ggetobj("drop", drop, 0);
  476.     if (*u.ushops) sellobj_state(FALSE);
  477.     reset_occupations();
  478.  
  479.     return result;
  480. }
  481.  
  482. #endif /* OVL0 */
  483. #ifdef OVL2
  484.  
  485. /* on a ladder, used in goto_level */
  486. static boolean NEARDATA at_ladder = FALSE;
  487.  
  488. int
  489. dodown()
  490. {
  491.     struct trap *trap = 0;
  492.  
  493.     if( (u.ux != xdnstair || u.uy != ydnstair)
  494.          && (!xdnladder || u.ux != xdnladder || u.uy != ydnladder)
  495.          && (!sstairs.sx || u.ux != sstairs.sx || u.uy != sstairs.sy
  496.             || sstairs.up)
  497.       ) {
  498.         if (!(trap = t_at(u.ux,u.uy)) || trap->ttyp != TRAPDOOR
  499.             || !Can_fall_thru(&u.uz) || !trap->tseen) {
  500.             You("can't go down here.");
  501.             return(0);
  502.         }
  503.     }
  504.     if(u.ustuck) {
  505.         You("are being held, and cannot go down.");
  506.         return(1);
  507.     }
  508.     if(Levitation) {
  509.         pline("You're floating high above the %s.",
  510.             levl[u.ux][u.uy].typ == STAIRS ? "stairs" :
  511.             levl[u.ux][u.uy].typ == LADDER ? "ladder" :
  512.             "trap door");
  513.         return(0);
  514.     }
  515.     if (on_level(&valley_level, &u.uz) && !u.uevent.gehennom_entered) {
  516.         You("are standing at the gate to Gehennom.");
  517.         pline("Unspeakable cruelty and harm lurk down there.");
  518.         if (yn("Are you sure you want to enter?") != 'y')
  519.              return(0);
  520.         else pline("So be it.");
  521.         u.uevent.gehennom_entered = 1;    /* don't ask again */
  522.     }
  523.  
  524. #ifdef WALKIES
  525.     if(!next_to_u()) {
  526.         You("are held back by your pet!");
  527.         return(0);
  528.     }
  529. #endif
  530.     if (trap)
  531. #ifdef POLYSELF
  532.         You("%s into the trap door.", locomotion(uasmon, "jump"));
  533. #else
  534.         You("jump into the trap door.");
  535. #endif
  536.     if (levl[u.ux][u.uy].typ == LADDER) at_ladder = TRUE;
  537.     next_level(!trap);
  538.     at_ladder = FALSE;
  539.     return(1);
  540. }
  541.  
  542. int
  543. doup()
  544. {
  545.     if( (u.ux != xupstair || u.uy != yupstair)
  546.          && (!xupladder || u.ux != xupladder || u.uy != yupladder)
  547.          && (!sstairs.sx || u.ux != sstairs.sx || u.uy != sstairs.sy
  548.             || !sstairs.up)
  549.        ) {
  550.         You("can't go up here.");
  551.         return(0);
  552.     }
  553.     if(u.ustuck) {
  554.         You("are being held, and cannot go up.");
  555.         return(1);
  556.     }
  557.     if(near_capacity() > SLT_ENCUMBER) {
  558.         /* No levitation check; inv_weight() already allows for it */
  559.         Your("load is too heavy to climb the %s.",
  560.               levl[u.ux][u.uy].typ == STAIRS ? "stairs" : "ladder");
  561.         return(1);
  562.     }
  563.     if(ledger_no(&u.uz) == 1) {
  564.         if (yn("Beware, there will be no return! Still climb?") != 'y')
  565.             return(0);
  566.     }
  567. #ifdef WALKIES
  568.     if(!next_to_u()) {
  569.         You("are held back by your pet!");
  570.         return(0);
  571.     }
  572. #endif
  573.     if (levl[u.ux][u.uy].typ == LADDER) at_ladder = TRUE;
  574.     prev_level(TRUE);
  575.     at_ladder = FALSE;
  576.     return(1);
  577. }
  578.  
  579. d_level save_dlevel = {0, 0};
  580.  
  581. /* check that we can write out the current level */
  582. static int
  583. currentlevel_rewrite()
  584. {
  585.     register int fd;
  586.  
  587.     fd = create_levelfile(ledger_no(&u.uz));
  588.  
  589.     if(fd < 0) {
  590.         /*
  591.          * This is not quite impossible: e.g., we may have
  592.          * exceeded our quota. If that is the case then we
  593.          * cannot leave this level, and cannot save either.
  594.          * Another possibility is that the directory was not
  595.          * writable.
  596.          */
  597.         pline("Cannot create level file for level %d.",
  598.                         ledger_no(&u.uz));
  599.         return -1;
  600.     }
  601.  
  602. #ifdef MFLOPPY
  603.     if (!savelev(fd, ledger_no(&u.uz), COUNT_SAVE)) {
  604.         (void) close(fd);
  605.         delete_levelfile(ledger_no(&u.uz));
  606.         pline("NetHack is out of disk space for making levels!");
  607.         You("can save, quit, or continue playing.");
  608.         return -1;
  609.     }
  610. #endif
  611.     return fd;
  612. }
  613.  
  614. #ifdef INSURANCE
  615. void
  616. save_currentstate()
  617. {
  618.     int fd;
  619.  
  620.     if (flags.ins_chkpt) {
  621.         /* write out just-attained level, with pets and everything */
  622.         fd = currentlevel_rewrite();
  623.         if(fd < 0) return;
  624.         bufon(fd);
  625.         savelev(fd,ledger_no(&u.uz), WRITE_SAVE);
  626.         bclose(fd);
  627.     }
  628.  
  629.     /* write out non-level state */
  630.     savestateinlock();
  631. }
  632. #endif
  633.  
  634. /*
  635. static boolean
  636. badspot(x, y)
  637. register xchar x, y;
  638. {
  639.         return((levl[x][y].typ != ROOM && levl[x][y].typ != AIR &&
  640.                  levl[x][y].typ != CORR) || MON_AT(x, y));
  641. }
  642. */
  643.  
  644. void
  645. goto_level(newlevel, at_stairs, falling, portal)
  646. d_level *newlevel;
  647. register boolean at_stairs, falling, portal;
  648. {
  649.     register int fd;
  650.     register boolean up = (depth(newlevel) < depth(&u.uz));
  651.     register boolean newdungeon = (u.uz.dnum != newlevel->dnum);
  652. #ifdef REINCARNATION
  653.     int new = 0;    /* made a new level? */
  654. #endif
  655.  
  656.     if(dunlev(newlevel) > dunlevs_in_dungeon(newlevel))
  657.             newlevel->dlevel = dunlevs_in_dungeon(newlevel);
  658.     if(newdungeon && In_endgame(newlevel)) { /* 1st Endgame Level !!! */
  659.             if(u.uhave.amulet) 
  660.             assign_level(newlevel, &earth_level);
  661.             else return;
  662.     }
  663.     if(ledger_no(newlevel) <= 0)
  664.             done(ESCAPED);    /* in fact < 0 is impossible */
  665.     /* If you have the amulet and are trying to get out of Hell, going
  666.      * up a set of stairs sometimes does some very strange things!
  667.      */
  668.     if(Inhell && up && !newdungeon && u.uhave.amulet &&
  669.                    (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz)-3)) {
  670.             if(!rn2(4)) {
  671.             if(!u.ualign.type) {            /* neutral */
  672.                 if(rn2(2)) assign_level(newlevel, &u.uz);
  673.                 else assign_rnd_level(newlevel, &u.uz, rnd(3));
  674.             } else if(u.ualign.type == A_LAWFUL) {    /* lawful */
  675.             assign_rnd_level(newlevel, &u.uz, rnd(3));
  676.             } else assign_level(newlevel, &u.uz); /* chaotic */
  677.             }
  678.         pline("A mysterious force momentarily surrounds you...");
  679.             if(ledger_no(newlevel) < 1) assign_level(newlevel, &u.uz);
  680.             if(on_level(newlevel, &u.uz)) {
  681.             (void) safe_teleds();
  682. #ifdef WALKIES
  683.             (void) next_to_u();
  684. #endif
  685.             return;
  686.         }
  687.     }
  688. #ifdef MULDGN
  689. /*    Prevent the player from going past the first quest level unless
  690.  *    (s)he has been given the go-ahead by the leader.
  691.  */
  692.     if(on_level(&u.uz, &qstart_level) && !newdungeon && !ok_to_quest()) {
  693.  
  694.         pline("A mysterious force prevents you from descending.");
  695.         return;
  696.     }
  697. #endif
  698.     if(on_level(newlevel, &u.uz)) return;          /* this can happen */
  699.  
  700.     fd = currentlevel_rewrite();
  701.     if(fd < 0) return;
  702.  
  703.     if (falling) /* assuming this is only trapdoor */
  704.         impact_drop((struct obj *)0, u.ux, u.uy, newlevel->dlevel);
  705.  
  706.     check_special_room(TRUE);        /* probably was a trap door */
  707.     if(Punished) unplacebc();
  708.     u.utrap = 0;                /* needed in level_tele */
  709.     fill_pit(u.ux, u.uy);
  710.     u.ustuck = 0;                /* idem */
  711.     u.uinwater = 0;
  712.     keepdogs();
  713.     if(u.uswallow)                /* idem */
  714.         u.uswldtim = u.uswallow = 0;
  715.     /*
  716.      *  We no longer see anything on the level.  Make sure that this
  717.      *  follows u.uswallow set to null since uswallow overrides all
  718.      *  normal vision.
  719.      */
  720.     vision_recalc(2);
  721.     bufon(fd);
  722.     savelev(fd,ledger_no(&u.uz), WRITE_SAVE | FREE_SAVE);
  723.     bclose(fd);
  724.  
  725. #ifdef REINCARNATION
  726.     if (Is_rogue_level(newlevel) || Is_rogue_level(&u.uz))
  727.         assign_rogue_graphics(Is_rogue_level(newlevel));
  728. #endif
  729.     assign_level(&u.uz0, &u.uz);
  730.     assign_level(&u.uz, newlevel);
  731.     assign_level(&u.utolev, newlevel);
  732.     u.utotype = 0;
  733.     if(dunlev_reached(&u.uz) < dunlev(&u.uz))
  734.         dunlev_reached(&u.uz) = dunlev(&u.uz);
  735.  
  736.     /* set default level change destination areas */
  737.     /* the special level code may override these */
  738.     (void) memset((genericptr_t) &updest, 0, sizeof updest);
  739.     (void) memset((genericptr_t) &dndest, 0, sizeof dndest);
  740.  
  741.     if(In_endgame(&u.uz) ||
  742. #ifdef MFLOPPY
  743.         /* If the level has no .where yet, it hasn't been made */
  744.         !fileinfo[ledger_no(&u.uz)].where) {
  745. #else
  746.         !level_exists[ledger_no(&u.uz)]) {
  747. #endif
  748.         mklev();
  749. #ifdef REINCARNATION
  750.         new = 1;    /* made the level */
  751. #endif
  752.     } else {
  753.         fd = open_levelfile(ledger_no(&u.uz));
  754.         if (fd < 0) {
  755.             pline("Cannot open file (#%d) for level %d (errno %d).",
  756.                     ledger_no(&u.uz), depth(&u.uz), errno);
  757.             pline("Probably someone removed it.");
  758.             done(TRICKED);
  759.         }
  760. #ifdef ZEROCOMP
  761.         minit();
  762. #endif
  763.         getlev(fd, hackpid, ledger_no(&u.uz), FALSE);
  764.         (void) close(fd);
  765.     }
  766. #ifdef MULDGN
  767.     quest_init();    /* re-initialize */
  768. #endif
  769.  
  770.     if(portal && !In_endgame(&u.uz)) {
  771.         /* find the portal on the new level */
  772.         register struct trap *ttrap;
  773.  
  774.         for(ttrap = ftrap; ttrap; ttrap = ttrap->ntrap)
  775.         if(ttrap->ttyp == MAGIC_PORTAL) break;
  776.  
  777.         if(ttrap) {
  778.         u.ux = ttrap->tx;
  779.         u.uy = ttrap->ty;
  780.         } else panic("goto_level: no corresponding portal!");
  781.     } else if(at_stairs && !In_endgame(&u.uz)) {
  782.         if(up) {
  783.         if(at_ladder) {
  784.             u.ux = xdnladder;
  785.             u.uy = ydnladder;
  786.         } else {
  787.             if(newdungeon) {
  788.             if(Is_stronghold(&u.uz)) {
  789.                 register xchar x, y;
  790.  
  791.                 do {
  792.                 x = (COLNO - 2 - rnd(5));
  793.                 y = rn1(ROWNO - 4, 3);
  794.                 } while(occupied(x, y) ||
  795.                     IS_WALL(levl[x][y].typ));
  796.                 u.ux = x;
  797.                 u.uy = y;
  798.             } else u_on_sstairs();
  799.             } else u_on_dnstairs();
  800.         } 
  801.         /* Remove bug which crashes with */ 
  802.         /* levitation/punishment  KAA    */
  803.         if(Punished) {
  804.             if(!Levitation)
  805.             pline("With great effort you climb the %s.",
  806.                   !at_ladder ? "stairs" : "ladder");
  807.             placebc();
  808.         } 
  809.         if(at_ladder && (!Punished || Levitation))
  810.             You("climb up the ladder.");
  811.         } else { /* down */
  812.         if(at_ladder) {
  813.             u.ux = xupladder;
  814.             u.uy = yupladder;
  815.         } else {
  816.             if(newdungeon) u_on_sstairs();
  817.             else u_on_upstairs();
  818.         }
  819.         if(at_stairs && u.dz && !up &&
  820.            ((near_capacity()>UNENCUMBERED) || Punished || Fumbling)) {
  821.             You("fall down the %s.",
  822.             !at_ladder ? "stairs" : "ladder");
  823.             if(Punished) {
  824.             drag_down();
  825.             if(carried(uball)) {
  826.                 if (uwep == uball)
  827.                 setuwep((struct obj *)0);
  828.                 if (uwep != uball)
  829.                 freeinv(uball);
  830.             }
  831.             placebc();
  832.             } 
  833.             losehp(rnd(3), "falling downstairs", KILLED_BY);
  834.             selftouch("Falling, you");
  835.         } 
  836.         else if(at_ladder && u.dz)
  837.             You("climb down the ladder.");
  838.         }
  839.     } else { /* trap door or level_tele or In_endgame */
  840.         if(up)
  841.         place_lregion(updest.lx, updest.ly,
  842.                   updest.hx, updest.hy,
  843.                   updest.nlx, updest.nly,
  844.                   updest.nhx, updest.nhy,
  845.                   LR_UPTELE, (d_level *) 0);
  846.         else
  847.         place_lregion(dndest.lx, dndest.ly,
  848.                   dndest.hx, dndest.hy,
  849.                   dndest.nlx, dndest.nly,
  850.                   dndest.nhx, dndest.nhy,
  851.                   LR_DOWNTELE, (d_level *) 0);
  852.         if(Punished) {
  853.         if(falling) ballfall();
  854.         placebc();
  855.         }
  856.         if(falling)
  857.         selftouch("Falling, you");
  858.     }
  859.  
  860.     losedogs();
  861.     obj_delivery();
  862.     check_special_room(FALSE);
  863.  
  864.     initrack();
  865.  
  866.     if(MON_AT(u.ux, u.uy)) mnexto(m_at(u.ux, u.uy));
  867.     if(MON_AT(u.ux, u.uy)) {
  868.         impossible("mnexto failed (do.c)?");
  869.         rloc(m_at(u.ux, u.uy));
  870.     }
  871.     remove_cadavers(&fobj);    /* remove rotted meat (before seen) */
  872.  
  873.     /* initial movement of bubbles just before vision_recalc */
  874.     if (Is_waterlevel(&u.uz))
  875.         movebubbles();
  876.  
  877.     /* Reset the screen. */
  878.     vision_reset();        /* reset the blockages */
  879.     docrt();        /* does a full vision recalc */
  880.  
  881.     /* In Nethack 3.1, Gehennom starts after the stronghold.  Moreover,
  882.      * there are traps in the stronghold, that can send the player
  883.      * to Gehennom (gnark, gnark)!  So we have to test here:
  884.      */
  885.     if(!In_hell(&u.uz0) && Inhell) {
  886.             if(Is_valley(newlevel)) {
  887.         You("arrive at the Valley of the Dead...");
  888.             pline("There is a smell of burnt flesh and decay here.");
  889. #ifdef MICRO
  890.             display_nhwindow(WIN_MESSAGE, FALSE);
  891. #endif
  892.         pline("The sounds of groans and moans fill the air.");
  893.         } else pline("It is hot here.  You smell smoke...");
  894.     }
  895.  
  896. #ifdef REINCARNATION
  897.     /*
  898.      *  Move all plines beyond the screen reset.
  899.      */
  900.     if (new && Is_rogue_level(&u.uz))
  901.      You("have entered what appears to be an older, more primitive world.");
  902. #endif
  903.     /* Final confrontation */
  904.     if (In_endgame(&u.uz) && newdungeon && u.uhave.amulet &&
  905.                            flags.no_of_wizards == 0)
  906.         resurrect();
  907.     if (newdungeon && In_tower(&u.uz))
  908.         pline("The heat and smoke are gone.");
  909. #ifdef MULDGN
  910.     if(!In_quest(&u.uz0) && at_dgn_entrance("The Quest") &&
  911.         !(u.uevent.qexpelled || u.uevent.qcompleted || leaderless()))
  912.         com_pager(2);    /* the message from the leader */
  913.  
  914.     if(Is_knox(&u.uz)) {
  915.             register struct monst *mtmp;
  916.  
  917.             You("penetrated a high security area!");
  918.         pline("An alarm sounds!");
  919.         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 
  920.             if(mtmp->msleep) mtmp->msleep = 0;
  921.     }
  922. #endif /* MULDGN */
  923.     if(on_level(&u.uz, &astral_level)) {
  924.             register struct monst *mtmp;
  925.  
  926.             /* reset monster hostility relative to player */
  927.         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 
  928.             reset_hostility(mtmp);
  929.  
  930.         /* create some player-monsters */
  931.         create_mplayers(rn1(4, 3), TRUE);
  932.  
  933.         /* create a guardian angel next to player, if worthy */
  934.         if (Conflict) {
  935.             coord mm;
  936.             int i = rnd(4);
  937.     pline("A voice booms: \"Thy desire for conflict shall be rewarded!\"");
  938.             while(i--) {
  939.             mm.x = u.ux;
  940.             mm.y = u.uy;
  941.             if(enexto(&mm, mm.x, mm.y, &mons[PM_ANGEL]))
  942.                 (void) mk_roamer(&mons[PM_ANGEL], u.ualign.type,
  943.                          mm.x, mm.y, FALSE);
  944.             }
  945.  
  946.         } else if(u.ualign.record > 3) {
  947.             coord mm;
  948.  
  949.         pline("A voice whispers: \"Thou hast been worthy of me!\"");
  950.             mm.x = u.ux;
  951.             mm.y = u.uy;
  952.             if(enexto(&mm, mm.x, mm.y, &mons[PM_ANGEL])) {
  953.             if((mtmp = mk_roamer(&mons[PM_ANGEL], u.ualign.type,
  954.                        mm.x, mm.y, TRUE)) != 0) {
  955.                  register struct obj *otmp =
  956.                                mksobj(SILVER_SABER, FALSE, FALSE);
  957.  
  958.                  if(!Blind)
  959.                          pline("An angel appears near you.");
  960.                  else 
  961.                You("feel the presence of a friendly angel near you.");
  962.                 /* guardian angel -- the one case mtame doesn't
  963.                  * imply an edog structure, so we don't want to
  964.                  * call tamedog().
  965.                  */
  966.                  mtmp->mtame = 10;
  967.                  /* make him strong enough vs. endgame foes */
  968.                  mtmp->m_lev = rn1(8,15);
  969.                  mtmp->mhp = mtmp->mhpmax = 
  970.                        d((int)mtmp->m_lev,10) + 30 + rnd(30);
  971.                  bless(otmp);
  972.                  otmp->spe = 7;
  973.                  mpickobj(mtmp, otmp);
  974.                 }
  975.             }
  976.         }
  977.         }
  978.  
  979. #ifdef MULDGN
  980.     onquest();
  981. #endif
  982.     assign_level(&u.uz0, &u.uz); /* reset u.uz0 */
  983.  
  984. #ifdef INSURANCE
  985.     save_currentstate();
  986. #endif
  987.  
  988.     if(!flags.nopick && OBJ_AT(u.ux, u.uy) &&
  989.        (!is_pool(u.ux,u.uy) || Underwater))
  990.         pickup(1);
  991.     else read_engr_at(u.ux,u.uy);
  992. }
  993.  
  994. /* handle something like portal ejection */
  995. void
  996. deferred_goto()
  997. {
  998.     if (!on_level(&u.uz, &u.utolev)) {
  999.         d_level dest;
  1000.         int typmask = u.utotype; /* save it; goto_level zeroes u.utotype */
  1001.  
  1002.         assign_level(&dest, &u.utolev);
  1003.         goto_level(&dest, !!(typmask&4), !!(typmask&2), !!(typmask&1));
  1004.         if (typmask & 0200) {    /* remove portal */
  1005.         deltrap(t_at(u.ux, u.uy));
  1006.         newsym(u.ux, u.uy);
  1007.         }
  1008.     }
  1009. }
  1010.  
  1011. #endif /* OVL2 */
  1012. #ifdef OVL3
  1013.  
  1014. void
  1015. revive_corpse(corpse, odds, mark_as_old)    /* see remove_cadavers() */
  1016. register struct obj *corpse;
  1017. int odds;
  1018. boolean mark_as_old;
  1019. {
  1020.     register struct monst *mtmp;
  1021.  
  1022.     corpse->oldcorpse = mark_as_old;
  1023.  
  1024.     /* odds == 0 is a special case meaning 'always revive' */
  1025.     if (!odds || !rn2(odds)) {
  1026.     if (carried(corpse)) {
  1027.         if (corpse == uwep) {
  1028.         if ((mtmp = revive(corpse,TRUE)) != 0)
  1029.             pline("The %s%s %s writhes out of your grasp!",
  1030.             (mtmp->mhp < mtmp->mhpmax) ? "bite-covered ":"",
  1031.                 mtmp->data->mname, xname(corpse));
  1032.         } else if ((mtmp = revive(corpse,TRUE)) != 0)
  1033.         You("feel squirming in your backpack!");
  1034.     } else {
  1035.         if ((mtmp = revive(corpse,FALSE)) && cansee(mtmp->mx,mtmp->my))
  1036.         pline("%s rises from the dead!",
  1037.             (mtmp->mhp==mtmp->mhpmax) ? Monnam(mtmp)
  1038.             : Adjmonnam(mtmp, "bite-covered"));
  1039.     }
  1040.     }
  1041. }
  1042.  
  1043. /*
  1044.  *  Remove old cadavers from any object chain.  Regenerate trolls
  1045.  *  thanks to KAA.  Follows containers (except ice boxes).
  1046.  */
  1047. #define TAINT_AGE    50    /* min. limit for tainting.  see eat.c */
  1048. #define ODDS_RV1    37    /* 1/37 odds for 50 moves = 75% revive */
  1049. #define ODDS_RV2    2    /* special case 1/2 odds of reviving */
  1050.  
  1051. void
  1052. remove_cadavers(chain)
  1053. struct obj **chain;
  1054. {
  1055.     register struct obj *obj, *nobj, *pobj = (struct obj *)0;
  1056.     register long corpse_age;
  1057.     boolean ininv = (*chain == invent);
  1058.     boolean onfloor = (*chain == fobj);
  1059.  
  1060.     for (obj = *chain; obj; obj = nobj) {
  1061.     nobj = obj->nobj;
  1062.  
  1063.     if (obj->otyp == CORPSE) {
  1064.         /* corpses laying on ice deteriorate more slowly */
  1065.         if (onfloor && obj->age < monstermoves &&
  1066.         rn2(3) && is_ice(obj->ox, obj->oy)) obj->age++;
  1067.         corpse_age = monstermoves - obj->age;
  1068.  
  1069.         if (is_rider(&mons[obj->corpsenm]) && corpse_age >= 12) {
  1070.         /* these always come back eventually */
  1071.         /* riders can't be picked up, so no need to check onfloor */
  1072.         revive_corpse(obj, 3, FALSE);
  1073.         } else if (mons[obj->corpsenm].mlet == S_TROLL && !obj->oldcorpse
  1074.                && !(mons[obj->corpsenm].geno & (G_GENOD | G_EXTINCT))
  1075.                && (onfloor || ininv)) {
  1076.  
  1077.         /* the corpse has 50 moves, the lower limit for tainting,
  1078.          * to attempt re-animation.  if it is unsuccessful it is
  1079.          * marked to prevent further attempts.  if we leave the
  1080.          * level and return to old corpses that haven't been marked
  1081.          * they're given a one-shot chance to re-animate.
  1082.          */
  1083.         if (corpse_age < TAINT_AGE)
  1084.             revive_corpse(obj, ODDS_RV1, FALSE);
  1085.         else if (corpse_age == TAINT_AGE)
  1086.             revive_corpse(obj, ODDS_RV1, TRUE);
  1087.         else revive_corpse(obj, ODDS_RV2, TRUE);
  1088.  
  1089.         } else if (obj->corpsenm != PM_LIZARD && (250 < corpse_age)) {
  1090.         if(ininv)
  1091.             useup(obj);
  1092.         else if(onfloor)
  1093.             delobj(obj);
  1094.         else { /* in a container */
  1095.             if(pobj) pobj->nobj = nobj;
  1096.             else *chain = nobj;
  1097.             obfree(obj, (struct obj *) 0);
  1098.             obj = 0;
  1099.         }
  1100.         }
  1101.     } else if(obj->cobj && Is_container(obj) && obj->otyp != ICE_BOX)
  1102.         remove_cadavers(&obj->cobj);
  1103.     /* pobj is only used for containers, which don't allow revive() -dlc */
  1104.     if (obj) pobj = obj;
  1105.     }
  1106. }
  1107.  
  1108. int
  1109. donull() {
  1110.     return(1);    /* Do nothing, but let other things happen */
  1111. }
  1112.  
  1113. #endif /* OVL3 */
  1114. #ifdef OVLB
  1115.  
  1116. STATIC_PTR int
  1117. wipeoff() {
  1118.     if(u.ucreamed < 4)    u.ucreamed = 0;
  1119.     else            u.ucreamed -= 4;
  1120.     if (Blinded < 4)    Blinded = 0;
  1121.     else            Blinded -= 4;
  1122.     if (!Blinded) {
  1123.         pline("You've got the glop off.");
  1124.         u.ucreamed = 0;
  1125.         Blinded = 1;
  1126.         make_blinded(0L,TRUE);
  1127.         return(0);
  1128.     } else if (!u.ucreamed) {
  1129.         Your("%s feels clean now.", body_part(FACE));
  1130.         return(0);
  1131.     }
  1132.     return(1);        /* still busy */
  1133. }
  1134.  
  1135. int
  1136. dowipe()
  1137. {
  1138.     if(u.ucreamed)  {
  1139.         static char NEARDATA buf[39];
  1140.  
  1141.         Sprintf(buf, "wiping off your %s", body_part(FACE));
  1142.         set_occupation(wipeoff, buf, 0);
  1143.         /* Not totally correct; what if they change back after now
  1144.          * but before they're finished wiping?
  1145.          */
  1146.         return(1);
  1147.     }
  1148.     Your("%s is already clean.", body_part(FACE));
  1149.     return(1);
  1150. }
  1151.  
  1152. #endif /* OVLB */
  1153. #ifdef OVL1
  1154.  
  1155. /* split obj so that it gets size num */
  1156. /* remainder is put in the object structure delivered by this call */
  1157. struct obj *
  1158. splitobj(obj, num)
  1159. register struct obj *obj;
  1160. register long num;
  1161. {
  1162. register struct obj *otmp;
  1163.     /* assert(0 < num && num < obj->quan); */
  1164.     otmp = newobj(obj->onamelth);
  1165.     *otmp = *obj;        /* copies whole structure */
  1166.     otmp->o_id = flags.ident++;
  1167.     obj->quan = num;
  1168.     obj->owt = weight(obj);
  1169.     otmp->quan -= num;
  1170.     otmp->owt = weight(otmp);    /* -= obj->owt ? */
  1171.     obj->nobj = obj->nexthere = otmp;
  1172.     if (obj->onamelth)
  1173.         (void)strncpy(ONAME(otmp), ONAME(obj), (int)obj->onamelth);
  1174.     if(obj->unpaid) splitbill(obj,otmp);
  1175.     return(otmp);
  1176. }
  1177.  
  1178. #endif /* OVL1 */
  1179. #ifdef OVLB
  1180.  
  1181. void
  1182. set_wounded_legs(side, timex)
  1183. register long side;
  1184. register int timex;
  1185. {
  1186.     if(!Wounded_legs) {
  1187.         ATEMP(A_DEX)--;
  1188.         flags.botl = 1;
  1189.     }
  1190.  
  1191.     if(!Wounded_legs || (Wounded_legs & TIMEOUT))
  1192.         Wounded_legs |= side + timex;
  1193.     else
  1194.         Wounded_legs |= side;
  1195. }
  1196.  
  1197. void
  1198. heal_legs()
  1199. {
  1200.     if(Wounded_legs) {
  1201.         if (ATEMP(A_DEX) < 0) {
  1202.             ATEMP(A_DEX)++;
  1203.             flags.botl = 1;
  1204.         }
  1205.  
  1206.         if((Wounded_legs & BOTH_SIDES) == BOTH_SIDES) {
  1207.             Your("%s feel somewhat better.",
  1208.                 makeplural(body_part(LEG)));
  1209.         } else {
  1210.             Your("%s feels somewhat better.",
  1211.                 body_part(LEG));
  1212.         }
  1213.         Wounded_legs = 0;
  1214.     }
  1215. }
  1216.  
  1217. #endif /* OVLB */
  1218.  
  1219. /*do.c*/
  1220.